package com.junzerg.tooltip.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.junzerg.tooltip.constant.Constant;
import com.junzerg.tooltip.controller.request.AmapPoiRequest;
import com.junzerg.tooltip.controller.response.AmapPoiResponse;
import com.junzerg.tooltip.entity.dao.ConvAmapAddressDao;
import com.junzerg.tooltip.service.IAmapService;
import com.junzerg.tooltip.service.IConvAmapAddressService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author pengjz <br>
 * @version 1.0 <br>
 * @description AmapServiceImpl <br>
 * @date 2022/4/10 16:38 <br>
 */
@Service
@Slf4j
public class AmapServiceImpl implements IAmapService {

    @Resource
    IConvAmapAddressService convAmapAddressService;

    /**
     * 用于刷新数据的线程池，允许任务丢失
     * 根据处理器数量新建线程
     */
    private final Executor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() + 1,
            Runtime.getRuntime().availableProcessors() + 1,
            Integer.MAX_VALUE,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingDeque<>(),
            new ThreadPoolExecutor.DiscardPolicy()
    );

    @Override
    public void getPlaceByTextFromAmap(String keywords, String types, String city, Boolean citylimit, Integer offset, Integer page) {
        // 高德poi关键字搜索
        this.execute(
                Constant.AMAP.POI_URL_TEXT,
                AmapPoiRequest.builder()
                        .keywords(keywords)
                        .types(types)
                        .city(city)
                        .citylimit(Boolean.toString(citylimit))
                        .offset(offset)
                        .page(page)
                        .build()
        );
//        executor.execute(() -> execute(
//                Constant.AMAP.POI_URL_TEXT,
//                AmapPoiRequest.builder()
//                        .keywords(keywords)
//                        .types(types)
//                        .city(city)
//                        .citylimit(Boolean.toString(citylimit))
//                        .offset(offset)
//                        .page(page)
//                        .build()
//        ));
    }

    @Override
    public void getPlaceByAroundFromAmap(String location, String keywords, String types, String city, Double radius, Integer offset, Integer page) {
        // 高德poi周边搜索
        executor.execute(() -> execute(
                Constant.AMAP.POI_URL_AROUND,
                AmapPoiRequest.builder()
                        .location(location)
                        .keywords(keywords)
                        .types(types)
                        .city(city)
                        .radius(Double.toString(radius))
                        .offset(offset)
                        .page(page)
                        .build()
        ));
    }

    @Override
    public void getPlaceByPolygonAmap(String polygon, String keywords, String types, Integer offset, Integer page) {
        // 高德poi多边形搜索
        executor.execute(() -> execute(
                Constant.AMAP.POI_URL_POLYGON,
                AmapPoiRequest.builder()
                        .polygon(polygon)
                        .keywords(keywords)
                        .types(types)
                        .offset(offset)
                        .page(page)
                        .build()
        ));
    }


    private void execute(String url, AmapPoiRequest request) {
        // 统一设定高德服务的key
        request.setKey(Constant.AMAP.AUTH_KEY);
        // 统一设定高德服务的key
        request.setKey(Constant.AMAP.AUTH_KEY);
        // 创建okHttp的请求客户端
        OkHttpClient okHttpClient = new OkHttpClient();
        Call call = okHttpClient.newCall(new Request.Builder().url(request.urlBuilder(url)).build());
        // 发起请求
        call.enqueue(new Callback() {
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                // 解析响应结果
                AmapPoiResponse poiResponse = JSONObject.parseObject(
                        Objects.requireNonNull(response.body()).string(),
                        AmapPoiResponse.class);
                if (Constant.AMAP.RESPONSE_INFO_OK.equals(poiResponse.getInfo())) {
                    poiResponse.getPois().forEach(
                            poi -> {
                                try {
                                    if (
                                            poi.getAddress().contains(request.getKeywords())
                                                    || poi.getName().contains(request.getKeywords())
                                    ) {
                                        convAmapAddressService.save(
                                                ConvAmapAddressDao.builder()
                                                        .addressName(poi.getName())
                                                        .convAddress(request.getKeywords())
                                                        .distinctName(poi.getAdname())
                                                        .build()
                                        );
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                    );
                } else {
                    log.warn(response.body().string());
                }
            }

            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                // 失败的话输出失败原因和异常
                log.warn(Constant.AMAP_ERROR.REQUEST_FAIL);
                e.printStackTrace();
            }
        });
    }
}
